package com.desin.modle.multithread;

import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

/**
 * 要注意:在这个类中f0到f7都在一个公共线池中，如果调用其构造方法，则这几个任务会一起执行
 */
public class CuCompletableFuture {


    //串行关系
    CompletableFuture<String> f0 =
            CompletableFuture.supplyAsync(
                    () -> "Hello World")      //①
                    .thenApply(s -> s + " QQ")  //②
                    .thenApply(String::toUpperCase);//③


    //任务1：洗水壶->烧开水
    CompletableFuture<Void> f1 =
            CompletableFuture.runAsync(
                    new Runnable() {
                        @Override
                        public void run() {
                            System.out.println("T1:洗水壶...");
                            sleep(1, TimeUnit.SECONDS);

                            System.out.println("T1:烧开水...");
                            sleep(15, TimeUnit.SECONDS);
                        }
                    }
//                    ()->{
//                System.out.println("T1:洗水壶...");
//                sleep(1, TimeUnit.SECONDS);
//
//                System.out.println("T1:烧开水...");
//                sleep(15, TimeUnit.SECONDS);
//            }
            );
    //任务2：洗茶壶->洗茶杯->拿茶叶
    CompletableFuture<String> f2 =
            CompletableFuture.supplyAsync(
                    new Supplier<String>() {
                        @Override
                        public String get() {
                            System.out.println("T2:洗茶壶...");
                            sleep(1, TimeUnit.SECONDS);

                            System.out.println("T2:洗茶杯...");
                            sleep(2, TimeUnit.SECONDS);

                            System.out.println("T2:拿茶叶...");
                            sleep(1, TimeUnit.SECONDS);
                            return "龙井";
                        }
                    }
//                    ()->{
//                System.out.println("T2:洗茶壶...");
//                sleep(1, TimeUnit.SECONDS);
//
//                System.out.println("T2:洗茶杯...");
//                sleep(2, TimeUnit.SECONDS);
//
//                System.out.println("T2:拿茶叶...");
//                sleep(1, TimeUnit.SECONDS);
//                return "龙井";
//            }
            );
    //and汇聚关系
    //任务3：任务1和任务2完成后执行：泡茶
    CompletableFuture<String> f3 =
            f1.thenCombine(f2, (__, tf) -> {
                System.out.println("T1:拿到茶叶:" + tf);
                System.out.println("T1:泡茶...");
                return "上茶:" + tf;
            });
////等待任务3执行结果
//System.out.println(f3.join());


    CompletableFuture<String> f4 =
            CompletableFuture.supplyAsync(()->{
                int t = getRandom(5, 10);
                sleep(t, TimeUnit.SECONDS);
                return String.valueOf(t);
            });

    CompletableFuture<String> f5 =
            CompletableFuture.supplyAsync(()->{
                int t = getRandom(5, 10);
                sleep(t, TimeUnit.SECONDS);
                return String.valueOf(t);
            });

    //or汇聚关系
    CompletableFuture<String> f6 =
            f4.applyToEither(f5,s -> s);


    //串行关系，异常
    CompletableFuture<Integer>
            f7 = CompletableFuture
    .supplyAsync(()->(7/0))
            .thenApply(r->r*10)
            .exceptionally(e->0);


    void sleep(int t, TimeUnit u) {
        try {
            u.sleep(t);
        } catch (InterruptedException e) {
        }
    }

    public int getRandom(int min, int max){
        Random random = new Random();
        int i = random.nextInt(max) % (max - min + 1) + min;
        return i;
    }

}
